﻿using System;
using System.Web.Mvc;
using Xenta.Utils;

namespace Xenta.Attributes
{
    /// <summary>
    /// Represents the attribute, which allows to define, 
    /// if the model state should be persisted in the 
    /// TempData dictionary after an action execution.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, 
        Inherited = true, AllowMultiple = false)]
    public sealed class PersistStateAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// Called by the ASP.NET MVC framework after the action method executes.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            var controller = filterContext.Controller;
            var modelState = controller.ViewData.ModelState;
            if(!modelState.IsValid)
                controller.TempData.PersistObject("ModelState", modelState);
            controller.TempData.PersistStatus(modelState.IsValid);
            base.OnActionExecuted(filterContext);
        }
    }

    /// <summary>
    /// Represents the attribute, which allows to define, if the model 
    /// state should be restored from the TempData dictionary, before 
    /// action will be executed.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method,
        Inherited = true, AllowMultiple = false)]
    public sealed class RestoreStateAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// Called by the ASP.NET MVC framework before the action method executes.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var controller = filterContext.Controller;
            var currentState = controller.ViewData.ModelState;
            var oldState = controller.TempData.RestoreObject<ModelStateDictionary>("ModelState");
            if(oldState != null)
                currentState.Merge(oldState);
            base.OnActionExecuting(filterContext);
        }
    }
}